//cardstack.cpp
//by Eric Norton
//2/13/02

#include <iostream.h>
#include "cardstack.h"

Card::Card()
{
	csuit=NULL;
	inum=NULL;
	next=NULL;
	prev=NULL;
}

void Card::operator=(const Card& copyme)
{
	//copy everything but pointers
	csuit=copyme.csuit;
	inum=copyme.inum;
}

Cardstack::Cardstack()
{
	head=NULL;
	tail=NULL;
	cursor=NULL;
	isize=0;
}

bool Cardstack::Give(const Card& newcard)
{
	//if empty Card
	if(newcard.csuit==NULL)
	{
		return false;
	}
	else
	{
		//if empty
		if(head==NULL)
		{
			head=new Card;
			tail=head;
			cursor=head;
		}
		//put on end of list
		else
		{
			tail->next=new Card;
			tail->next->prev=tail;
			tail=tail->next;
		}
		//what tail points to becomes copy of newcard
		*tail=newcard;
		isize+=1;

		return true;
	}
}

bool Cardstack::Givehead(const Card& newcard)
{
	if(newcard.csuit==NULL)
	{
		return false;
	}
	else
	{
		//if empty
		if(head==NULL)
		{
			head=new Card;
			tail=head;
			cursor=head;
		}
		//else put on head of list
		else
		{
			head->prev=new Card;
			head->prev->next=head;
			head=head->prev;
		}
		//what tail points to becomes copy of newcard
		*head=newcard;
		isize+=1;

		return true;
	}
}

void Cardstack::Zap()
{
	cursor=head;
	//if any Cards in list
	if(cursor!=NULL)
	{
		//while not at end of list
		while(head->next!=NULL)
		{
			//progressively delete Cards from beginning
			//to end
			head=head->next;
			delete cursor;
			cursor=head;
		}
		//delete last Card
		delete cursor;
	}
	head=NULL;		//make sure it doesn't point anywhere
	tail=NULL;
	cursor=NULL;
	isize=0;	//list is empty
}

void Cardstack::Print()
{
	int ix=1;	//for endl

	cursor=head;	//start at beginning
	if(cursor!=NULL)
	{
		//output each Card from beginning to end
		while(cursor->next!=NULL)
		{
			cout<<cursor->inum;
			cout<<cursor->csuit<<" ";
			if(ix%IRACE==0)
				cout<<endl;	//endl every IRACE cards
			ix+=1;
			cursor=cursor->next;
		}
		cout<<cursor->inum;
		cout<<cursor->csuit;
		cout<<endl;
	}
}

Card Cardstack::Take(int iCard)
{
	Card copy;	//copy of Card to be destroyed
	int ix;		//for finding the iCardth Card

	cursor=head;
	ix=0;
	//travel to iCardth Card if iCard is valid, else go to
	//head or tail
	while(cursor!=NULL&&cursor->next!=NULL&&ix<iCard)
	{
		cursor=cursor->next;
		ix+=1;
	}
	copy=*cursor;		//make copy a copy of iCardth Card
	//if iCard==1 and there's more Cards left
	if(cursor==head&&cursor!=NULL&&cursor->next!=NULL)
	{
		head=head->next;
		delete head->prev;
		head->prev=NULL;
	}
	//else if no Cards left
	else if(cursor==head&&cursor!=NULL)
	{
		delete head;
		head=NULL;
		tail=NULL;
		cursor=NULL;
	}
	//else if it was the last Card
	else if(cursor==tail)
	{
		tail=tail->prev;
		delete tail->next;
		tail->next=NULL;
	}
	//else if it was a Card in the middle
	else if(cursor!=NULL)
	{
		cursor->prev->next=cursor->next;
		cursor->next->prev=cursor->prev;
		delete cursor;
	}
	//if list wasn't empty to begin with
	if(isize>0)
	{
		isize-=1;
	}
	return copy;
}

bool Cardstack::Shuffle()
{
	int ix;			//for finding irandth Card
	int irand;		//random Card
	Card storecard;	//for storing *cursor
	Card* cursor2;	//points at the irandth Card

	//if 1 or less Cards in list
	if(isize<2)
	{
		return false;
	}
	else
	{
		//start at beginning
		cursor=head;
		do
		{
			storecard=*cursor;		//store Card
			cursor2=head;			//pick random Card		
			irand=Random();
			for(ix=0;ix<irand;ix++)
			{
				cursor2=cursor2->next;
			}
			*cursor=*cursor2;		//swap them
			*cursor2=storecard;
			cursor=cursor->next;
		}while(cursor->next!=NULL);		//next Card
		
		return true;
	}
}

int Cardstack::Time()
{
	struct _timeb timebuffer;	//records time

	_ftime(&timebuffer);		//getting time
	return timebuffer.millitm;	//returning milliseconds
}

int Cardstack::Random()
{
	int irand;
	
	do
	{
		irand=((rand()*isize)/RAND_MAX);
	//make absolutely sure irand is within bounds
	}while(irand<0||irand>=isize);

	return irand;
}

Card Cardstack::Getcard(int inum)
{
	Card copycard;
	int ix=0;

	cursor=head;
	if(cursor!=NULL)
	{
		while(ix<inum&&cursor->next!=NULL)
		{
			cursor=cursor->next;
			ix+=1;
		}
		copycard=*cursor;
	}
	return copycard;
}

Cardstack::~Cardstack()
{
	Zap();
}